﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using RCREEE.Library;
using RCREEE.Library.Entities;

namespace RCREEE.Web
{
    public partial class SitemapHandler : System.Web.UI.Page
    {
        #region Properties
        private string SS_AllNodes = "AllNodes";
        private string SS_CurrentNode = "CurrentNode";
        private string SS_SelectedParentNode = "SelectedParentNode";
        private string SS_EntityTypes = "EntityTypes";
        private string SS_LangCode = "LanguageCode";

        public List<CustomSiteMapNode> AllNodes
        {
            get
            {
                if (Session[SS_AllNodes] != null)
                    return (List<CustomSiteMapNode>)Session[SS_AllNodes];

                return new List<CustomSiteMapNode>();
            }
            set
            {
                Session[SS_AllNodes] = value;

            }
        }

        public CustomSiteMapNode CurrentNode
        {
            get
            {
                if (Session[SS_CurrentNode] != null)
                    return (CustomSiteMapNode)Session[SS_CurrentNode];

                return new CustomSiteMapNode();
            }
            set
            {
                Session[SS_CurrentNode] = value;

            }
        }

        public CustomSiteMapNode SelectedParentNode
        {
            get
            {
                if (Session[SS_SelectedParentNode] != null)
                    return (CustomSiteMapNode)Session[SS_SelectedParentNode];

                return new CustomSiteMapNode();
            }
            set
            {
                Session[SS_SelectedParentNode] = value;

            }
        }


        public List<Item> EntityTypes
        {
            get
            {
                if (Session[SS_EntityTypes] != null)
                    return (List<Item>)Session[SS_EntityTypes];

                return new List<Item>();
            }
            set
            {
                Session[SS_EntityTypes] = value;

            }
        }

        public int LanguageCode
        {
            get
            {
                int langCode = 0;
                if (Session[SS_LangCode] != null)
                    int.TryParse(Session[SS_LangCode].ToString(), out langCode);
                return langCode;
            }
            set
            {
                Session[SS_LangCode] = value;
            }
        }
        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //LanguageCode = (int)LanguagesEnum.English;
                List<CustomSiteMapNode> list = new List<CustomSiteMapNode>();
                //list.Add(new CustomSiteMapNode { SiteMapNodeId = 1, Url = "https://www.google.com/", ParentId = 0 });
                //list.Add(new CustomSiteMapNode { SiteMapNodeId = 2, Url = "https://www.gmail.com/", ParentId = 1 });
                //list.Add(new CustomSiteMapNode { SiteMapNodeId = 3, Url = "https://www.yahoo.com/", ParentId = 0 });

                EntityTypes = DataManager.GetItemsByLanguageAndCategory((int)LanguagesEnum.English,
                                                                                (int)CategoriesEnum.EntityType);
                ddlTypes.DataSource = EntityTypes.Where(t => t.ItemID != (int)EntityTypesEnum.Other);
                ddlTypes.DataBind();

                CurrentNode = new CustomSiteMapNode();

                RefereshSitemapNodes();
            }
            ExpandTrees();
        }

        protected override void InitializeCulture()
        {
            if (LanguageCode > 0)
            {
                string languageId = "en-US";
                if (LanguageCode == (int)LanguagesEnum.French)
                    languageId = "fr-FR";
                if (LanguageCode == (int)LanguagesEnum.Arabic)
                    languageId = "ar-EG";
                if (LanguageCode == (int)LanguagesEnum.English)
                    languageId = "en-US";
                Thread.CurrentThread.CurrentCulture =
                CultureInfo.CreateSpecificCulture(languageId);

                Thread.CurrentThread.CurrentUICulture = new CultureInfo(languageId);
            }

            base.InitializeCulture();
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
            ExpandTrees();
        }

        private void ExpandTrees()
        {
            treesiteMap.ExpandAll();
            treeParents.ExpandAll();
        }

        private void RefereshSitemapNodes()
        {
            AllNodes = DataManager.GetSiteMapNodes(LanguageCode);
            treesiteMap.Nodes.Clear();
            treeParents.Nodes.Clear();


            BindTree(treesiteMap, AllNodes, null);
            BindTree(treeParents, AllNodes, null);
        }

        private void BindTree(TreeView treeView, IEnumerable<CustomSiteMapNode> list, TreeNode parentNode)
        {
            var nodes = list.Where(x => parentNode == null ? x.ParentId == 0 : x.ParentId == int.Parse(parentNode.Value));
            foreach (var node in nodes)
            {
                //TreeNode newNode = new TreeNode(node.Url, node.SiteMapNodeId.ToString(), "", node.Url,"");
                TreeNode newNode = new TreeNode(node.Title.Name, node.SiteMapNodeId.ToString());
                if (parentNode == null)
                {
                    treeView.Nodes.Add(newNode);
                }
                else
                {
                    parentNode.ChildNodes.Add(newNode);
                }
                BindTree(treeView, list, newNode);
            }
        }

        protected void SiteMapTree_SelectedNodeChanged(object sender, EventArgs e)
        {
            int selectedNodeId;
            if (int.TryParse(treesiteMap.SelectedValue, out selectedNodeId) && selectedNodeId > 0)
            {
                CurrentNode = AllNodes.FirstOrDefault(n => n.SiteMapNodeId == selectedNodeId);
                if (CurrentNode != null)
                {
                    BindCurrentNode();
                }
            }
        }

        private void BindCurrentNode()
        {
            if (CurrentNode != null)
            {
                txtEntityEnglish.Text = CurrentNode.EntityItem.EnglishName;
                txtEntityArabic.Text = CurrentNode.EntityItem.ArabicName;
                txtEntityFrench.Text = CurrentNode.EntityItem.FrenchName;

                txtTitleEnglish.Text = CurrentNode.TitleItem.EnglishName;
                txtTitleArabic.Text = CurrentNode.TitleItem.ArabicName;
                txtTitleFrench.Text = CurrentNode.TitleItem.FrenchName;

                if (CurrentNode.SiteMapNodeId > 0)
                {
                    ddlTypes.Enabled =
                    rdCadreEntity.Enabled = rdNormalEntity.Enabled = false;
                    ddlTypes.DataSource = EntityTypes;
                    ddlTypes.DataBind();
                }
                else
                {
                    ddlTypes.Enabled =
                    rdCadreEntity.Enabled = rdNormalEntity.Enabled = true;
                    ddlTypes.DataSource = EntityTypes.Where(t => t.ItemID != (int)EntityTypesEnum.Other);
                    ddlTypes.DataBind();
                }

                if (CurrentNode.EntityTypeId > 0)
                {
                    ddlTypes.SelectedValue = CurrentNode.EntityTypeId.ToString();

                }

                if (CurrentNode.SiteMapNodeId > 0 && (CurrentNode.Entity == null || CurrentNode.Entity.ID == 0))
                {
                    rdCadreEntity.Checked = true;
                    rdNormalEntity.Checked = false;
                    MultiView.ActiveViewIndex = 1;

                    editorEnglish.Text = CurrentNode.EnglishContent != null ? CurrentNode.EnglishContent.Content : string.Empty;
                    editorArabic.Text = CurrentNode.ArabicContent != null ? CurrentNode.ArabicContent.Content : string.Empty;
                    editorFrench.Text = CurrentNode.FrenchContent != null ? CurrentNode.FrenchContent.Content : string.Empty;

                    txtEnglishDescription.Text =
                    txtArabicDescription.Text =
                    txtFrenchDescription.Text = string.Empty;
                }
                else
                {
                    rdNormalEntity.Checked = true;
                    rdCadreEntity.Checked = false;
                    MultiView.ActiveViewIndex = 0;
                    editorEnglish.Text = editorArabic.Text = editorFrench.Text = string.Empty;
                    txtEnglishDescription.Text = CurrentNode.EntityItem.EnglishDescription;
                    txtArabicDescription.Text = CurrentNode.EntityItem.ArabicDescription;
                    txtFrenchDescription.Text = CurrentNode.EntityItem.FrenchDescription;
                }

                SelectedParentNode = AllNodes.FirstOrDefault(n => n.SiteMapNodeId == CurrentNode.ParentId);
                if (SelectedParentNode != null)
                {
                    SetSelectedItem(treeParents.Nodes);
                    BindParentNode();
                }
                if (CurrentNode.SiteMapNodeId > 0 && !CurrentNode.NestedNodes.Any() && CurrentNode.EntityTypeId != (long)EntityTypesEnum.Other)
                {
                    btnDelete.Enabled = true;
                }
                else
                {
                    btnDelete.Enabled = false;
                }
            }
        }

        private void SetSelectedItem(TreeNodeCollection treeViewNodes)
        {
            foreach (TreeNode node in treeViewNodes)
            {
                if (node.Value == SelectedParentNode.SiteMapNodeId.ToString())
                {
                    node.Selected = true;
                }
                SetSelectedItem(node.ChildNodes);
            }
        }

        protected void TreeParents_SelectedNodeChanged(object sender, EventArgs e)
        {
            int selectedParentNodeId;
            if (int.TryParse(treeParents.SelectedValue, out selectedParentNodeId) && selectedParentNodeId > 0)
            {
                SelectedParentNode = AllNodes.FirstOrDefault(n => n.SiteMapNodeId == selectedParentNodeId);
                if (SelectedParentNode != null)
                {
                    BindParentNode();
                }
            }
        }

        private void BindParentNode()
        {
            ddlLevel.Items.Clear();
            if (SelectedParentNode != null && SelectedParentNode.SiteMapNodeId > 0)
            {
                int newItemCounter = CurrentNode.SiteMapNodeId > 0 ? 0 : 1;
                for (int i = 0; i < SelectedParentNode.NestedNodes.Count + newItemCounter; i++)
                {
                    string value = (i + 1).ToString();
                    ddlLevel.Items.Add(new ListItem(value, value));
                }
                if (CurrentNode.Level > 0 && ddlLevel.Items.FindByValue(CurrentNode.Level.ToString())!=null)
                {
                    ddlLevel.SelectedValue = CurrentNode.Level.ToString();
                }
            }
        }

        protected void BtnSave_Clicked(object sender, EventArgs e)
        {
            CurrentNode.TitleItem.EnglishName = txtTitleEnglish.Text;
            CurrentNode.TitleItem.ArabicName = txtTitleArabic.Text;
            CurrentNode.TitleItem.FrenchName = txtTitleFrench.Text;

            if (rdNormalEntity.Checked)
            {
                CurrentNode.EntityItem.EnglishDescription = txtEnglishDescription.Text;
                CurrentNode.EntityItem.FrenchDescription = txtFrenchDescription.Text;
                CurrentNode.EntityItem.ArabicDescription = txtArabicDescription.Text;
                CurrentNode.IsContentNode = false;

                CurrentNode.EntityItem.EnglishName = txtEntityEnglish.Text;
                CurrentNode.EntityItem.ArabicName = txtEntityArabic.Text;
                CurrentNode.EntityItem.FrenchName = txtEntityFrench.Text;
            }
            else if (rdCadreEntity.Checked)
            {
                CurrentNode.IsContentNode = true;
                if (CurrentNode.EnglishContent != null)
                {
                    CurrentNode.EnglishContent.Content = editorEnglish.Text;
                }
                else
                {
                    CurrentNode.SitemapNodeContents.Add(new SitemapNodeContent
                    {
                        SiteMapNodeId = CurrentNode.SiteMapNodeId,
                        Content = editorEnglish.Text,
                        ContentTypeId = (int)ContentTypesEnum.Content1,
                        LanguageCode = (int)LanguagesEnum.English
                    });
                }
                if (CurrentNode.ArabicContent != null)
                {
                    CurrentNode.ArabicContent.Content = editorArabic.Text;
                }
                else
                {
                    CurrentNode.SitemapNodeContents.Add(new SitemapNodeContent
                    {
                        SiteMapNodeId = CurrentNode.SiteMapNodeId,
                        Content = editorArabic.Text,
                        ContentTypeId = (int)ContentTypesEnum.Content1,
                        LanguageCode = (int)LanguagesEnum.Arabic
                    });
                }
                if (CurrentNode.FrenchContent != null)
                {
                    CurrentNode.FrenchContent.Content = editorFrench.Text;
                }
                else
                {
                    CurrentNode.SitemapNodeContents.Add(new SitemapNodeContent
                    {
                        SiteMapNodeId = CurrentNode.SiteMapNodeId,
                        Content = editorFrench.Text,
                        ContentTypeId = (int)ContentTypesEnum.Content1,
                        LanguageCode = (int)LanguagesEnum.French
                    });
                }
            }

            #region HandleEntityType
            if (rdNormalEntity.Checked)
            {
                int selectedEntityType;
                if (int.TryParse(ddlTypes.SelectedValue, out selectedEntityType) && selectedEntityType > 0)
                {
                    CurrentNode.EntityTypeId = CurrentNode.EntityItem.ParentItemId = selectedEntityType;
                    if (selectedEntityType != null)
                    {
                        switch ((EntityTypesEnum)selectedEntityType)
                        {
                            case EntityTypesEnum.Project:
                                CurrentNode.Url = "~/project.aspx?e=";
                                break;
                            case EntityTypesEnum.Contact:
                                CurrentNode.Url = "~/contact.aspx?e=";
                                break;
                            case EntityTypesEnum.Item:
                                CurrentNode.Url = "~/ItemsList.aspx?e=";
                                break;
                        }
                        // Handel content page
                        if (CurrentNode.SiteMapNodeId > 0 && CurrentNode.Entity.ID > 0)
                        {
                            CurrentNode.Url += CurrentNode.Entity.ID;
                        }
                    }
                }
            }
            else if (rdCadreEntity.Checked)
            {
                //CurrentNode.EntityTypeId = (int)EntityTypesEnum.Item;
                CurrentNode.Url = "~/content.aspx?n=";

                // Handel content page
                if (CurrentNode.SiteMapNodeId > 0)
                {
                    CurrentNode.Url += CurrentNode.SiteMapNodeId;
                }
            }

            #endregion

            #region Handel Levels
            List<CustomSiteMapNode> changedSiblingNodes = new List<CustomSiteMapNode>();
            int oldLevel = CurrentNode.Level;
            int level;
            if (int.TryParse(ddlLevel.SelectedValue, out level) && level > 0)
            {
                CurrentNode.Level = level;
            }

            var nodeWithTheSameLevel =
                SelectedParentNode.NestedNodes.FirstOrDefault(node => node.Level == CurrentNode.Level);

            if (nodeWithTheSameLevel != null)
            {
                if (CurrentNode.SiteMapNodeId == 0)
                {
                    var lastNodeLevel =
                        SelectedParentNode.NestedNodes.OrderBy(node => node.Level).Last().Level;
                    nodeWithTheSameLevel.Level = lastNodeLevel + 1;
                    changedSiblingNodes.Add(nodeWithTheSameLevel);
                }
                else
                {
                    nodeWithTheSameLevel.Level = oldLevel;
                    changedSiblingNodes.Add(nodeWithTheSameLevel);
                }
            }
            if (SelectedParentNode != null && SelectedParentNode.SiteMapNodeId > 0)
            {
                CurrentNode.ParentId = SelectedParentNode.SiteMapNodeId;
            }
            else
            {

            }
            #endregion

            #region Commented Handle Levels old approche

            //if (SelectedParentNode != null && SelectedParentNode.SiteMapNodeId > 0)
            //{
            //    CurrentNode.ParentId = SelectedParentNode.SiteMapNodeId;
            //    if (CurrentNode.Level > oldLevel)
            //    {
            //        foreach (var customSiteMapNode in SelectedParentNode.NestedNodes)
            //        {
            //            // Check for update all next sibiling except the current node
            //            if (customSiteMapNode.Level > oldLevel && customSiteMapNode.Level <= CurrentNode.Level && customSiteMapNode.SiteMapNodeId != CurrentNode.SiteMapNodeId)
            //            {
            //                customSiteMapNode.Level -= 1;
            //                changedSiblingNodes.Add(customSiteMapNode);
            //            }
            //        }
            //    }
            //    else if (CurrentNode.Level < oldLevel)
            //    {
            //        foreach (var customSiteMapNode in SelectedParentNode.NestedNodes)
            //        {
            //            // Check for update all next sibiling except the current node
            //            if (customSiteMapNode.Level < oldLevel && customSiteMapNode.Level >= CurrentNode.Level && customSiteMapNode.SiteMapNodeId != CurrentNode.SiteMapNodeId)
            //            {
            //                customSiteMapNode.Level += 1;
            //                changedSiblingNodes.Add(customSiteMapNode);
            //            }
            //        }
            //    }

            //    //foreach (var customSiteMapNode in SelectedParentNode.NestedNodes)
            //    //{
            //    //    // Check for update all next sibiling except the current node
            //    //    if (customSiteMapNode.Level >= CurrentNode.Level && customSiteMapNode.SiteMapNodeId != CurrentNode.SiteMapNodeId)
            //    //    {
            //    //        customSiteMapNode.Level += 1;
            //    //        changedSiblingNodes.Add(customSiteMapNode);
            //    //    }
            //    //}
            //} 
            #endregion

            DataManager.SaveSiteMapNode(CurrentNode);
            DataManager.EditSiblingNodes(changedSiblingNodes);

            CurrentNode = new CustomSiteMapNode();
            BindCurrentNode();
            RefereshSitemapNodes();
        }

        protected void BtnNew_Clicked(object sender, EventArgs e)
        {
            CurrentNode = new CustomSiteMapNode();
            BindCurrentNode();
            RefereshSitemapNodes();
        }

        protected void RdEntityCatCheckedChanged(object sender, EventArgs e)
        {
            if (rdNormalEntity.Checked)
            {
                MultiView.ActiveViewIndex = 0;
            }
            else if (rdCadreEntity.Checked)
            {
                MultiView.ActiveViewIndex = 1;
            }
            ClearViewData();
        }

        private void ClearViewData()
        {
            txtEnglishDescription.Text = txtFrenchDescription.Text = txtArabicDescription.Text =
                editorEnglish.Text = editorArabic.Text = editorFrench.Text = string.Empty;
        }

        protected void BtnDelete_Clicked(object sender, EventArgs e)
        {
            if (CurrentNode.SiteMapNodeId > 0)
            {
                if (DataManager.DeleteSiteMapNode(CurrentNode))
                {
                    List<CustomSiteMapNode> changedSiblingNodes = new List<CustomSiteMapNode>();
                    foreach (CustomSiteMapNode customSiteMapNode in SelectedParentNode.NestedNodes)
                    {
                        if (customSiteMapNode.Level > CurrentNode.Level)
                        {
                            customSiteMapNode.Level -= 1;
                            changedSiblingNodes.Add(customSiteMapNode);
                        }
                    }
                    DataManager.EditSiblingNodes(changedSiblingNodes);
                }
                CurrentNode = new CustomSiteMapNode();
                BindCurrentNode();
                RefereshSitemapNodes();
            }
        }
    }
}